package com.sharing.service;

import com.sharing.backgroundmodule.dto.UserProductionHobby;
import com.sharing.common.Page;
import com.sharing.common.Result;
import com.sharing.domain.BrowseRecord;
import com.sharing.domain.User;
import com.sharing.domain.UserHobby;
import com.sharing.domain.UserProduction;
import com.sharing.mapper.BrowseRecordMapper;
import com.sharing.mapper.UserMapper;
import com.sharing.util.ThreadLocalStorage;
import com.sun.corba.se.impl.oa.toa.TOA;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.w3c.dom.ls.LSException;

import javax.xml.crypto.dsig.SignedInfo;
import java.util.List;
import java.util.Objects;

/**
 * @author MingTian
 * @version 1.0
 * @description TODO
 * @date 2023/4/14 13:02
 */
@Service
public class BrowseRecordService {
    @Autowired
    private BrowseRecordMapper browseRecordMapper;

    @Autowired
    private UserService userService;

    @Autowired
    private UserProductionService userProductionService;

    @Autowired
    private UserMapper userMapper;

    /**
     * 根据用户id查询浏览记录表中该用户的浏览作品记录的业务层方法
     * @param userId
     * @param page
     * @param size
     * @return
     */
    public Result<Page<UserProduction>> selectBrowseRecordsByUserId(Integer userId, Integer page, Integer size) {
        // 校验该用户是否存在
        if (userId == null) {
            return new Result<>(1, "userId不能为空");
        }
        User user = userService.selectUserById(userId).getData();
        if (user == null) {
            return new Result<>(1, "该用户不存在");
        }

        // 校验分页参数
        if (page == null || size == null) {
            return new Result<>(1, "请传入合适的page和size参数");
        }

        // 校验userId
        User loginUser = ThreadLocalStorage.getUser();
        // 处理并发问题————双重检查+synchonized锁机制
        if (loginUser == null) {
            synchronized (this) {
                if (loginUser == null) {
                    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
                    loginUser = userMapper.selectUserByUserName(authentication.getName());
                    ThreadLocalStorage.setUser(loginUser);
                }
            }
        }
        if (!userId.equals(loginUser.getId())) {
            return new Result<>(1, "没有权限");
        }

        // 查询总数
        Integer total = browseRecordMapper.selectBrowseRecordNumByUserId(userId);

        // 根据分页条件从浏览记录表中查询该用户的浏览作品id
        List<Integer> productionIds = browseRecordMapper.selectBrowseRecordsByUserId(userId, (page - 1) * size, size);

        // 从作品表中查询作品的基本信息
        List<UserProduction> userProductions = userProductionService.selectUserProductionsByIds(productionIds).getData();

        return new Result<>(0, new Page<>(total, size, userProductions));
    }

    /**
     * 根据主键查询浏览记录的业务层方法
     * @param ids
     * @return
     */
    public Result<List<BrowseRecord>> selectBrowseRecordsByIds(List<Integer> ids) {
        if (ids == null || ids.size() == 0) {
            return new Result<>(1, "参数不当");
        }

        List<BrowseRecord> browseRecords = browseRecordMapper.selectBrowseRecordsByIds(ids);

        return new Result<>(0, browseRecords);
    }

    /**
     * 新增浏览记录
     * @param browseRecord
     * @return
     */
    public Result<BrowseRecord> insertBrowseRecord(BrowseRecord browseRecord) {
        // 校验参数一：
        if (browseRecord == null || browseRecord.getProductionId() == null) {
            return new Result<>(1, "参数不完整，请重新添加参数");
        }

        // 校验参数二：
        UserProduction userProduction = userProductionService.selectUserProductionById(browseRecord.getProductionId()).getData();
        if (userProduction == null) {
            return new Result<>(1, "该作品不存在");
        }

        // 校验参数三：
        User loginUser = ThreadLocalStorage.getUser();
        // 处理并发问题————双重检查+synchonized锁机制
        if (loginUser == null) {
            synchronized (this) {
                if (loginUser == null) {
                    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
                    loginUser = userMapper.selectUserByUserName(authentication.getName());
                    ThreadLocalStorage.setUser(loginUser);
                }
            }
        }
        if (browseRecord.getUserId() != null && !Objects.equals(browseRecord.getUserId(), loginUser.getId())) {
            return new Result<>(1, "参数中用户名id错误");
        }
        browseRecord.setUserId(loginUser.getId());

        // 通过BrowseRecordMapper数据层新增浏览记录
        Integer rows = browseRecordMapper.insertBrowseRecord(browseRecord);

        if (rows != 1) {
            return new Result<>(1, "新增失败");
        }

        return new Result<>(0, browseRecord);
    }

    /**
     * 删除浏览记录(后台)
     * 此处业务层方法用于后台删除过期历史浏览记录，不对用户开发
     * @param ids
     * @return
     */
    public Result<Integer> deleteBrowseRecords(List<Integer> ids) {
        // 校验参数
        if (ids == null || ids.size() == 0) {
            return new Result<>(1, "参数不完整，请重新添加参数");
        }

        Integer rows = browseRecordMapper.deleteBrowseRecords(ids);

        return new Result<>(0, rows);
    }

    /**
     * 删除浏览记录（用户）
     * @param ids
     * @return
     */
    public Result<Integer> deleteBrowseRecordsByUser(List<Integer> ids) {
        // 校验参数
        if (ids == null || ids.size() == 0) {
            return new Result<>(1, "参数不完整，请重新添加参数");
        }

        // 用户层面删除浏览记录————本质上就是为浏览记录的is_delete赋值为1
        Integer rows = browseRecordMapper.deleteBrowseRecordsByUser(ids);

        return new Result<>(0, rows);
    }

    /**
     * 从某一日的浏览记录中查询当日登陆过的用户浏览比例超过百分之50的兴趣
     * @param users 用户id
     * @param format 日期
     * @return
     */
    public List<UserHobby> selectHotHobbyByUserIds(List<Integer> users, String format) {
        List<UserHobby> userHobbies = browseRecordMapper.selectHotHobbyByUserIds(users, format);

        return userHobbies;
    }

    /**
     * 查询某用户从指定起始日期开始的浏览记录中作品对应的兴趣
     * @param userId
     * @param begin
     * @return
     */
    public List<UserProductionHobby> selectUserProductionHobbyByUserIdAndBeginDate(Integer userId, String begin) {
        List<UserProductionHobby> userProductionHobbies = browseRecordMapper.selectUserProductionHobbyByUserIdAndBeginDate(userId, begin);

        return userProductionHobbies;
    }
}
